home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 428_01 / ed / buffers.c < prev   
Encoding:
C/C++ Source or Header  |  1994-03-13  |  5.1 KB  |  258 lines

  1. /*
  2. ** buffers.c
  3. **
  4. ** Ed, Version 1.51, Copyright (c) 1992-94 SoftCircuits
  5. ** Redistributed by permission.
  6. */
  7.  
  8. #include <stdio.h>
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include <pictor.h>
  12. #include "ed.h"
  13.  
  14. char buffer[BUFSIZ];     /* general purpose buffer */
  15. int num_lines = 0;        /* number of lines in file */
  16. int line_ndx = 0;       /* index to current position */
  17. int file_row = 0;       /* file row - 1 */
  18. int file_col = 0;       /* file column - 1 */
  19. int pref_col = 0;       /* preffered column */
  20. int top_row = 0;        /* line at top of window */
  21. int left_col = 0;       /* column at left of window */
  22. int update_state = UPDATE_NOUPDATE;
  23.  
  24. LINE *head = NULL;      /* first line in file */
  25. LINE *tail = NULL;      /* last line in file */
  26. LINE *curr_line = NULL; /* current line */
  27. LINE *top_line = NULL;  /* line at top of window */
  28.  
  29. int tab_size = 8;       /* tab displacement */
  30. int insert_mode = TRUE; /* insert mode */
  31.  
  32. char untitled[] = "<Untitled>";
  33.  
  34. /*
  35. ** releases all line buffers in the linked list
  36. */
  37. void free_list()
  38. {
  39.     LINE *line,*next;
  40.  
  41.     for(line = head;line != NULL;line = next) {
  42.         next = line->next;
  43.         free(line);
  44.     }
  45.  
  46.     top_row = left_col = pref_col = line_ndx = file_row = file_col = 0;
  47.     head = tail = curr_line = top_line = NULL;
  48.     num_lines = 0;
  49.  
  50. } /* free_list */
  51.  
  52. /*
  53. ** removes the specified line buffer from the linked
  54. ** list
  55. */
  56. void remove_from_list(LINE *line)
  57. {
  58.     if(head == line) head = line->next;
  59.     if(tail == line) tail = line->prev;
  60.  
  61.     if(top_line == line) top_line = line->next;
  62.  
  63.     if(line->next != NULL)
  64.         line->next->prev = line->prev;
  65.     if(line->prev != NULL)
  66.         line->prev->next = line->next;
  67.  
  68.     num_lines--;
  69.  
  70.     free(line);
  71.  
  72. } /* remove_from_list */
  73.  
  74. /*
  75. ** inserts a line into the current buffer after pos
  76. */
  77. void add_to_list(LINE *line,LINE *pos)
  78. {
  79.     if(tail == pos) tail = line;
  80.  
  81.     line->prev = pos;
  82.     line->next = pos->next;
  83.  
  84.     pos->next = line;
  85.     if(line->next) line->next->prev = line;
  86.  
  87.     num_lines++;
  88.  
  89. } /* add_to_list */
  90.  
  91. /*
  92. ** appends a line to the linked list
  93. */
  94. void append_line(LINE *line)
  95. {
  96.     if(head == NULL) {
  97.         head = line;
  98.         line->prev = NULL;
  99.     }
  100.     else {
  101.         tail->next = line;
  102.         line->prev = tail;
  103.     }
  104.     line->next = NULL;
  105.     tail = line;
  106.  
  107.     num_lines++;
  108.  
  109. } /* append_line */
  110.  
  111. /*
  112. ** prepare buffers for new file
  113. ** if there is not enough memory even for one line of text,
  114. ** this function terminates the program
  115. ** note that this should never result in loss of data since
  116. ** we were creating a new file anyway
  117. */
  118. void new_file(char *fname)
  119. {
  120.     LINE *new;
  121.  
  122.    clrstatus();
  123.     free_list();
  124.  
  125.     new = malloc(sizeof(LINE));
  126.     if(new == NULL) {
  127.         messagebox("Out of memory\nUnable to continue","Error",MB_OK,
  128.             &msgcolors);
  129.         vcolor(foreback(WHITE,BLACK));
  130.         cls();
  131.         exit(-1);
  132.     }
  133.  
  134.     head = tail = new;
  135.     new->prev = NULL;
  136.     new->next = NULL;
  137.     new->len = 0;
  138.  
  139.     /* initialize buffer state */
  140.     curr_line = top_line = head;
  141.     num_lines = 1;
  142.  
  143.     strcpy(filename,(fname == NULL) ? untitled : fname);
  144.     modified = FALSE;
  145.     update_state = UPDATE_REPAINT;
  146.     update_cursor(TRUE);
  147.  
  148. } /* new_file */
  149.  
  150. /*
  151. ** reads the current file into memory
  152. */
  153. void load_file(char *fname)
  154. {
  155.     FILE *stream;
  156.     LINE *line;
  157.     int len,had_newline = FALSE;
  158.  
  159.     /* open input file */
  160.     stream = fopen(fname,"rt");
  161.     if(stream == NULL) {
  162.         new_file(fname);
  163.         return;
  164.     }
  165.  
  166.    xprintf(statusbar,"Loading: %s",fname);
  167.  
  168.     /* clear existing buffers */
  169.     free_list();
  170.  
  171.     /* read file into buffers */
  172.     while(fgets(buffer,BUFSIZ,stream)) {
  173.         len = strlen(buffer);
  174.         if(buffer[len - 1] == '\n')
  175.             had_newline = TRUE;
  176.         else
  177.             had_newline = FALSE;
  178.         if(had_newline)
  179.             len--;
  180.         line = (LINE *)malloc(sizeof(LINE) + len);
  181.         if(line == NULL) {
  182.             fclose(stream);
  183.             outofmemory();
  184.             new_file(untitled);
  185.             return;
  186.         }
  187.         strncpy(line->text,buffer,len);
  188.         line->len = len;
  189.         append_line(line);
  190.     }
  191.     /* append a blank line to follow last new-line */
  192.     if(had_newline) {
  193.         line = (LINE *)malloc(sizeof(LINE));
  194.         if(line == NULL) {
  195.             fclose(stream);
  196.             outofmemory();
  197.             new_file(untitled);
  198.             return;
  199.         }
  200.         line->len = 0;
  201.         append_line(line);
  202.     }
  203.     fclose(stream);
  204.  
  205.     if(num_lines == 0) {
  206.         new_file(fname);
  207.         return;
  208.     }
  209.  
  210.     /* initialize buffer state */
  211.     curr_line = top_line = head;
  212.  
  213.     strcpy(filename,fname);
  214.     modified = FALSE;
  215.     update_state = UPDATE_REPAINT;
  216.     update_cursor(TRUE);
  217.  
  218. } /* load_file */
  219.  
  220. /*
  221. ** saves the current file to disk
  222. */
  223. int save_file(char *fname)
  224. {
  225.     FILE *stream;
  226.     LINE *line;
  227.  
  228.     pushstatus();
  229.     xprintf(statusbar,"Saving: %s",fname);
  230.  
  231.     /* open file for writing */
  232.     stream = fopen(fname,"wt");
  233.     if(stream != NULL) {
  234.         /* write file from buffers */
  235.         for(line = head;line != NULL;line = line->next) {
  236.             fwrite(line->text,sizeof(char),line->len,stream);
  237.             if(line->next != NULL)
  238.                 fputc('\n',stream);
  239.             if(ferror(stream))
  240.                 break;
  241.         }
  242.     }
  243.     popstatus();
  244.     if(stream == NULL || ferror(stream)) {
  245.         messagebox("Error saving file to disk","Error",MB_OK,&msgcolors);
  246.         fclose(stream);
  247.         return(FALSE);
  248.     }
  249.     fclose(stream);
  250.  
  251.     strcpy(filename,fname);
  252.     modified = FALSE;
  253.     show_status();
  254.  
  255.     return(TRUE);
  256.  
  257. } /* save_file */
  258.